﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Sudum
{
	public class Sudum : Microsoft.Xna.Framework.Game
	{
		SpriteFont debugTextFont;
		StateFlow stateFlow;
    
	#if SHOW_PERFORMANCE    
		PerformanceCounter performanceCounter;
	#endif // SHOW_PERFORMANCE

		public Sudum()
		{
			Me = this;
			AGDN.Polyline.Init();
			new GraphicsDeviceManager(this);
			Content.RootDirectory = "Content";
			stateFlow = new StateFlow();
		}

		public static Sudum Me { set; get; }
		public SpriteFont DebugTextFont { get { return debugTextFont; } }

		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize()
		{
			base.Initialize();
		}

		/// <summary>
		/// LoadContent will be called once per game and is the place to load
		/// all of your content.
		/// </summary>
		protected override void LoadContent()
		{
		#if SHOW_PERFORMANCE
			performanceCounter = new PerformanceCounter();
			debugTextFont = Content.Load<SpriteFont>("DebugMessages");
		#endif // SHOW_PERFORMANCE
		}

		/// <summary>
		/// UnloadContent will be called once per game and is the place to unload
		/// all content.
		/// </summary>
		protected override void UnloadContent()
		{
		#if SHOW_PERFORMANCE
			performanceCounter.Dispose();
		#endif // SHOW_PERFORMANCE
		}

		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update(GameTime gameTime)
		{
		#if SHOW_PERFORMANCE
			performanceCounter.Start();
		#endif // SHOW_PERFORMANCE

			base.Update(gameTime);

			// Sudum updates. Note that we work in a fixed framerate mode. The update time delta is always going to be 1/60 MS.
			// Thus, there is no need to pass gameTime around in the code.
			InputManager.Me.Update(); // Update input manager first, so further reads in the various states are correct
            if (!stateFlow.Update()) // Update the currently active state
				Exit();
		}

		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw(GameTime gameTime)
		{
			base.Draw(gameTime);
            stateFlow.Render();

		#if SHOW_PERFORMANCE
			performanceCounter.End();
			performanceCounter.Draw();
		#endif // SHOW_PERFORMANCE
		}
	}
}
